package org.mv.mm.docs.nodes;

import java.util.List;
import java.util.logging.Logger;
import javax.swing.Action;
import org.mv.mm.api.Doc;
import org.mv.mm.api.capabilities.IRefreshableDocViewCapability;
import org.mv.mm.api.data.IDataProvider;
import org.mv.mm.common.CentralLookup;
import org.mv.mm.docs.DocNewType;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.util.Utilities;
import org.openide.util.datatransfer.NewType;
import org.openide.util.lookup.AbstractLookup;
import org.openide.util.lookup.InstanceContent;

/**
 *
 * @author Martin
 */
public final class DocRootNode extends AbstractNode {

  private IDataProvider dataProvider;
  private InstanceContent instanceContent;
  private DocNewType docType = null;
  private static final Logger logger = Logger.getLogger(DocRootNode.class.getName());

  /**
   * Constructor which prepares attributes for the parent constructor of
   * AbstractNode.
   *
   * @param DocRootNodeChildFactory
   */
  public DocRootNode(IDataProvider dataProvider) {
    this(dataProvider, new InstanceContent());
  }

  /**
   * Private constructor
   *
   * @param DocRootNodeChildFactory
   * @param ic
   */
  private DocRootNode(IDataProvider dataProvider, InstanceContent ic) {
    super(Children.create(new DocRootNodeChildFactory(dataProvider), true), new AbstractLookup(ic));

    this.dataProvider = dataProvider;
    this.instanceContent = ic;

    docType = new DocNewType(dataProvider, true);
    instanceContent.add(docType);

    CentralLookup centralLookup = CentralLookup.getDefault();

    // Add a new ability for this node to be reloaded
    IRefreshableDocViewCapability rvc = new IRefreshableDocViewCapability() {

      @Override
      public void refreshChildren() throws Exception {
        // To reload this node just set a new set of children
        // using a DocRootNodeChildFactory object, that retrieves
        // children asynchronously
        for (Node node : DocRootNode.this.getChildren().getNodes()) {
          CentralLookup cl = CentralLookup.getDefault();
          cl.remove(node);
        }
        setChildren(Children.create(new DocRootNodeChildFactory(DocRootNode.this.dataProvider), true));
      }

      @Override
      public void refreshAfterDelete() throws Exception {
        for (Node node : DocRootNode.this.getChildren().getNodes()) {
          CentralLookup cl = CentralLookup.getDefault();
          cl.remove(node);
        }
        setChildren(Children.create(new DocRootNodeChildFactory(DocRootNode.this.dataProvider), true));
      }

      @Override
      public void refreshAfterNew() throws Exception {
        for (Node node : DocRootNode.this.getChildren().getNodes()) {
          CentralLookup cl = CentralLookup.getDefault();
          cl.remove(node);
        }
        setChildren(Children.create(new DocRootNodeChildFactory(DocRootNode.this.dataProvider), true));

      }

      @Override
      public void refreshAfterEdit(Doc doc) throws Exception {
        // nothing yet
      }
      
      @Override
      public boolean canRefresh() {
        return true;
      }
    };
    this.instanceContent.add(rvc);
    centralLookup.add(rvc);
  }

  @Override
  public String getDisplayName() {
    return "Documents";
  }

  @SuppressWarnings("unchecked")
  @Override
  public Action[] getActions(boolean context) {
    List<Action> docActions = (List<Action>) Utilities.actionsForPath("Actions/RootNode");

    //docActions.add(PasteAction.get(PasteAction.class));
    //TODO k něčemu? docActions.add(ReorderAction.get(ReorderAction.class));

    return docActions.toArray(new Action[docActions.size()]);
  }

  /**
   * Without this method, the NewAction does nothing on the root node.
   *
   * @return DocNewType instance, which is called by action NewAction
   * (registered in layer.xml)
   */
  @Override
  public NewType[] getNewTypes() {
    return new NewType[]{docType};
  }

  /*
   * @Override public PasteType getDropType(final Transferable t, int arg1, int
   * arg2) { if (t.isDataFlavorSupported(FragmentFlavor.CHAPTER_FLAVOR)) {
   * return new PasteType() {
   *
   * @Override public Transferable paste() throws IOException { try {
   *
   *
   * final Node node = NodeTransfer.node(t, NodeTransfer.DND_MOVE +
   * NodeTransfer.CLIPBOARD_CUT); if (node != null) { node.destroy(); } //}
   * catch (UnsupportedFlavorException ex) { // logger.log(Level.WARNING, null,
   * ex); //TODO provide a message from Bundle } catch (Exception e) {
   * logger.log(Level.WARNING, null, e); //TODO provide a message from Bundle }
   * return null; } }; } else { return null; }
  }
   */

  /*
   * @Override protected void createPasteTypes(Transferable t, List<PasteType>
   * s) { super.createPasteTypes(t, s); PasteType p = getDropType(t, 0, 0); if
   * (p != null) { s.add(p); }
  }
   */
}
